//
//  RtcEngine.swift
//  OnemeetingDemo
//
//  Created by 张衡 on 2020/4/10.
//  Copyright © 2020 www.onemeeting.1meetingIos. All rights reserved.
//

import Foundation
import ZoomSDK

class RtcEngine: NSObject {
     
    static let shared = RtcEngine()
    
    var viewController:BaseViewController?
    var questionMode:WebSocketMode?
    
    //var dataL:SJHostModel?
    //var mode:SJMeetingMode?
    
    lazy var kZoomView: KIcon = {
        let view = KIcon.init(data: KIconGroup.init(title: "管理".localized(), image: "icon_custom"))
        view.tap = { zView in
            self.aco(senber: zView)
        }
        return view
    }()
    
    func setupAfterCustom() {
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+1.5) {
            self.setupCustomZoom()
        }
    }
    
    func setupCustomZoom() {
        
        guard let view = self.zoomView() else {
            return
        }
        
        for (_,val) in view.subviews.enumerated(){
            if val.className == "ZMSilentModeFrameView" {
                for (_,info2) in val.subviews.enumerated() {
                    if info2.isKind(of: NSImageView.classForCoder()) {
                        let imageV = info2 as? NSImageView
                        imageV?.image = NSImage.imageNamed("icon_pro_agree")
                        info2.wantsLayer = true
                        info2.layer?.borderColor = color_random_rgba().cgColor
                        info2.layer?.borderWidth = 10
                    }
                }
            }
            
            //tabar
            if val.className == "ZPConfToolbarView" {
                val.addSubview(kZoomView)
                kZoomView.snp.makeConstraints { (make) in
                    make.centerY.equalToSuperview()
                    make.width.equalTo(70)
                    make.height.equalToSuperview()
                    make.left.equalTo(190)
                }
            }
            
        }
        
         if let isOnLive = UserInfoManager.shared.isOnLive {
            self.kZoomView.isHidden = !isOnLive
        }
    }
    
    
    func addNotification() {
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+0.2) {
            NotificationCenter.default.addObserver(self, selector: #selector(self.receiveQustion(not:)), name: MTReceiveQustionNotification, object: nil)
        }
    }
    
    func aco(senber:NSView)  {
        
        let dataL:[KIconGroup] = [
            KIconGroup.init(title: "启动直播", image: "icon_clive"),
            KIconGroup.init(title: "问卷调查", image: "icon_qustion"),
        ]
        
        let menuVc =  AmuneViewController()
        menuVc.dataL = dataL
        menuVc.delegate = self
        let window = SharedWindow.shared
        window.level = NSWindow.Level(rawValue: Int(kCGScreenSaverWindowLevel))
        window.contentViewController = menuVc
        window.orderFront(nil)
        
    }
    
    func voteAction() {
        
        guard let mode = self.questionMode,let questionid = mode.questionid else {
            show_msg("请等待主持人推送完问卷后，再次尝试".localized())
            return
        }
        var dict:[String:String] = [:]
        dict["actid"] = UserInfoManager.shared.roomId
        dict["loginid"] = UserInfoManager.shared.ownid
        dict["loginname"] = UserInfoManager.shared.disname
        let urlString = mt_url_philipsquestionnaire+String(questionid).url(parms: dict)
        let encoding = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) ?? ""
        let vote = VoteViewController.init(url: URL.init(string:encoding)!)
        
        let window = SharedWindow.shared
        window.level = NSWindow.Level(rawValue: Int(kCGScreenSaverWindowLevel))
        window.contentViewController = vote
        window.orderFront(nil)
    }
    
    func zoomView() -> NSView? {
        guard let window = self.zoomWindow()  else {
            return nil
        }
        let view = window.contentView?.subviews[0]
        return view
    }
    
    func zoomWindow() -> NSWindow? {
        let window = NSApplication.shared.mainWindow
        if window?.className == "ZPConfMainWindow" {
            return window
        }
       return nil
    }
    
    class func saveDataJoin(mode:SJJoinModel) {
        UserInfoManager.shared.hostId = mode.joinid
        UserInfoManager.shared.zak = mode.zak
        UserInfoManager.shared.token = mode.token
    }
    
    class func saveDataHost(mode:SJHostModel) {
        
        UserInfoManager.shared.LiveURL = mode.liveurl
        UserInfoManager.shared.LiveToken = mode.livetoken
        UserInfoManager.shared.PlayUrl = mode.playurl
        UserInfoManager.shared.isOnLive = (mode.living == 0) ? false:true
        
        //有时yhthostmeeting接口会出现问题
        UserInfoManager.shared.roomId = mode.ownId.clear_ownid()
    }
    
    /// 设置默认数据
    /// - Parameter model: 数据mode
    class func saveData(mode:SJMeetingMode) {
        UserInfoManager.shared.ownid = mode.ownid.clear_ownid()
        UserInfoManager.shared.time = mode.time
        UserInfoManager.shared.disname = mode.display_name
        
        UserInfoManager.shared.kPassword = mode.password
        UserInfoManager.shared.ownidKey = mode.wifiId
        
        
        UserInfoManager.shared.activity_name = mode.activity_name
        UserInfoManager.shared.order_time = mode.order_time
    }
       
    class func saveLoginData(mode:SJMemMode) {
        UserInfoManager.shared.ownid = mode.data?.ownid
        UserInfoManager.shared.disname = mode.data?.name
        UserInfoManager.shared.time = mode.data?.time
        
        UserInfoManager.shared.photo = mode.data?.image_path
        UserInfoManager.shared.memid = mode.data?.memid.toString()
        UserInfoManager.shared.checkCode = mode.data?.checkCode
        
        UserInfoManager.shared.activity_name = mode.data?.activity_name
        UserInfoManager.shared.order_time =  mode.data?.order_time
    }
    
    //扫码登录格式和一般登录格式不一样
    class func saveQRLoginData(mode:QRMemMode) {
        UserInfoManager.shared.ownid = mode.ownid
        UserInfoManager.shared.disname = mode.name
        UserInfoManager.shared.time = mode.time

        UserInfoManager.shared.photo = mode.image_path
        UserInfoManager.shared.memid = mode.memid.toString()
        UserInfoManager.shared.checkCode = mode.checkCode

        UserInfoManager.shared.activity_name = mode.activity_name
        UserInfoManager.shared.order_time = mode.order_time
    }
    
    
    class func noData() -> Bool {
        if UserInfoManager.shared.ownid != nil && UserInfoManager.shared.time != nil {
            return false
        }
        return true
    }
    
    class func isNoData() -> Bool {
        let isok = RtcEngine.noData()
        if isok == true {
            show_msg("请刷新，获取数据！".localized())
        }
        return isok
    }
    
    
    class func handurlPatamts(params: [String:Any]?, type: RtcType) {
        guard let dparams = params else {
            return
        }
        
        let ownid = (dparams["ownId"] as? String)
        let name = (dparams["name"] as? String)
        let activityId = dparams["activityId"] as? String
        let roomId = (dparams["roomId"] as? String)
        let pwd = (dparams["word"] as? String)
        
        let ktoken = dparams["token"] as? String
        let kzak = dparams["zak"] as? String
        let khostId = dparams["hostId"] as? String
        
        //name的检测
        let display_name = UserInfoManager.shared.disname ?? ""
        let username = display_name == "" ? mt_defualt_name:display_name
        let kName = name ?? username
        let newUsername = kName.removingPercentEncoding!
        
        switch type {
        case .join:
            if (dparams.keys.contains("ownId")){
                let newOwnId = ownid!.clear_ownid()
                var mData = MBefineData()
                mData.roomid = newOwnId
                mData.username = newUsername
                mData.hostId = khostId
                mData.zak = kzak
                mData.token = ktoken
                mData.password = pwd
                NotificationCenter.default.post(name: MTDoMeetingNotification, object: mData)
                return
            }
            
            if (dparams.keys.contains("roomId")){
                var mData = MBefineData()
                mData.roomid = "0"+roomId!
                mData.username = newUsername
                mData.hostId = khostId
                mData.zak = kzak
                mData.token = ktoken
                mData.password = pwd
                NotificationCenter.default.post(name: MTDoMeetingNotification, object: mData)
                return
            }
            
            //律时在线
            if (dparams.keys.contains("activityId")){
                var mData = MBefineData()
                mData.roomid = activityId
                mData.encryption = "律时在线".localized()
                mData.username = display_name
                mData.hostId = khostId
                mData.zak = kzak
                mData.token = ktoken
                NotificationCenter.default.post(name: MTDoMeetingNotification, object: mData)
                return
            }
            
            
        case .host:
            if (dparams.keys.contains("roomId")){
                if (dparams["roomId"] != nil) && (dparams["ownId"] != nil) {
                    let newOwnid = ownid!.clear_ownid()
                    let number = roomId ??  UserInfoManager.shared.roomId
                    let token = ktoken ?? UserInfoManager.shared.token
                    let zak = kzak ??  UserInfoManager.shared.zak
                    let hostId = khostId ?? UserInfoManager.shared.hostId
                    
                    var mData = MBefineData()
                    mData.roomid = newOwnid
                    mData.number = number
                    mData.ownid = newOwnid
                    mData.username = newUsername
                    mData.hostId = hostId
                    mData.zak = zak
                    mData.token = token
                    mData.isJoin = false
                    NotificationCenter.default.post(name: MTDoMeetingNotification, object: mData)
                  
                }
            }
        }
    }
    
    
    /// 获取号码，刷新主界面数据，并且进入主持会议
    /// - Parameter success: 成功后回调
    class func responseDataHostAndDo(parmas:[String:Any],success:(([String:AnyObject])->())? = nil){
        HUD.show()
        
        RtcEngine.responseDataHost { (result) in
            guard let ownid = parmas["number"] as? String else {
                return
            }
            NetEngine.respose_yhthost(ownid: ownid, success: { (result) in
                guard let mode = SJHostModel.deserialize(from: result) else {
                    return
                }
                RtcEngine.saveDataHost(mode: mode)
                net_delay(time: 0.3) {
                    let disname = (parmas["username"] as? String) ?? mt_defualt_name
                    
                    var info = ZoomApiInfo()
                    info.userID = mode.hostId
                    info.meetingNumber = mode.roomId
                    info.displayName = disname
                    info.userToken = mode.token
                    info.zak = mode.zak
                    info.isAuidoOff = UserInfoManager.shared.onAudio!
                    info.isVideoOff = UserInfoManager.shared.onVideo!
                    RtcEngine.doHostMeeting(info: info)
                }
                if success != nil {
                    success!(result)
                }
            }, fail: nil)
            
            
            
        }
    }
    
    
    /// 获取号码，刷新主界面数据，然后加入会议
    /// - Parameter number: 号码
    /// - Parameter success: 成功后回调
    class func responseDataJoinAndDoAndHost(parmas:[String:Any],success:(([String:AnyObject])->())? = nil) {
        HUD.show()
        RtcEngine.responseDataHost { (result) in
            self.responseDataJoin(parmas: parmas) { (kresult) in
                if success != nil {
                    success!(kresult)
                }
            }
        }
    }
    
}
//MARK:- RTC封装
extension RtcEngine {
    
    /// 获取会议号
    /// - Parameter success: 成功后回调
    class func responseMeetingID(success:(([String:AnyObject])->())? = nil){
        let ownidKey = UserInfoManager.shared.ownidKey ?? ""
        NetEngine.respose_getMeetingNum(ownidKey: ownidKey, success: { (result) in
            let mode = SJMeetingMode.deserialize(from: result)
            RtcEngine.saveData(mode: mode!)
            if success != nil {
                success!(result)
            }
        }, fail: nil)
    }
    
    
    /// 登录后获取会议号
    /// - Parameter success: 成功后回调
    class func responseUserInfo(success:(([String:AnyObject])->())? = nil,cacal:(()->())? = nil){
        
        guard let memid = UserInfoManager.shared.memid,let checkCode = UserInfoManager.shared.checkCode else {
            if cacal != nil {
                cacal!()
            }
            return
        }
        
        NetEngine.respose_userInfo(memid: memid, checkCode: checkCode, success: { (result) in
            let mode = SJMemMode.deserialize(from: result)
            if mode != nil {
                RtcEngine.saveLoginData(mode:mode!)
            }
            if success != nil {
                success!(result)
            }
        }){
            if cacal != nil {
                cacal!()
            }
        }
    }
    
    /// 获取会议号，然后获取主界面数据并存取
    /// - Parameter success: 成功后回调
    class func responseDataHost(success:(([String:AnyObject])->())? = nil) {
        if UserInfoManager.shared.isLogin == true {
            RtcEngine.responseUserInfo(success: { (result) in
                if success != nil {
                    success!(result)
                }
            }) {
                HUD.dismiss()
                show_msg("校验码已过期，请重新登录".localized())
                UserInfoManager.shared.isLogin = false
                UserInfoManager.shared.memid = nil
                UserInfoManager.shared.checkCode = nil
                NotificationCenter.default.post(name: MTLoginStateNotification, object: nil)
            }
        }else {
            RtcEngine.responseMeetingID { (mtResult) in
                if success != nil {
                    success!(mtResult)
                }
            }
        }
        
    }
    
    
    
    /// 获取加入会议接口，并加入会议
    /// - Parameters:
    ///   - parmas: 会议号，名称。字典格式
    ///   - success: 成功后回调
    class func responseDataJoin(parmas:[String:Any],success:(([String:AnyObject])->())? = nil){
        
        if self.noData() == true {
            show_msg("请刷新，获取数据！".localized())
            return
        }
       
        let number      = parmas["number"] as? String
        let activityId  = parmas["activityId"] as? String
        let username    = parmas["username"] as? String
        let password    = parmas["password"] as? String
        let encryption  = parmas["encryption"] as? String
        
        let ktoken = parmas["token"] as? String
        let kzak = parmas["zak"] as? String
        let khostId = parmas["hostId"] as? String
        
        if activityId != nil {
            NetEngine.getJoinActivityId(activityId: activityId!) { (result) in
                let mode = ActivityIdMode.deserialize(from: result)
                guard let token = mode?.token ?? UserInfoManager.shared.token,let hostId = mode?.hostId ?? UserInfoManager.shared.hostId,let zak = mode?.zak ?? UserInfoManager.shared.zak else {
                    show_msg("请先加入任意一个6位会议，获取有效的token".localized())
                    return
                }
                    
                var info = ZoomApiInfo()
                info.meetingNumber = mode?.roomId.toString()
                info.displayName = username!
                info.userID = hostId
                info.userToken = token
                info.zak = zak
                info.isAuidoOff = UserInfoManager.shared.onAudio!
                info.isVideoOff = UserInfoManager.shared.onVideo!
                info.password = mode?.password
                info.encryption = encryption
                RtcEngine.doJoinMeeting(info: info)
                if success != nil {
                    success!(result)
                }
            }
        }
        
        if number != nil {
             if number![(number?.startIndex)!] == "0" {
                guard let token = ktoken ?? UserInfoManager.shared.token,let hostId = khostId ?? UserInfoManager.shared.hostId,let zak = kzak ?? UserInfoManager.shared.zak else {
                    show_msg("请先加入任意一个6位会议，获取有效的token".localized())
                    return
                }
                
                let trueNumber = number?.substring(fromIndex: 1)
                var info = ZoomApiInfo()
                info.userID = hostId
                info.meetingNumber = trueNumber
                info.displayName = username
                info.userToken = token
                info.zak = zak
                info.isAuidoOff = UserInfoManager.shared.onAudio!
                info.isVideoOff = UserInfoManager.shared.onVideo!
                info.password = password
                RtcEngine.doJoinMeeting(info: info)
                
                if success != nil {
                    success!([:])
                }
            } else {
                guard let ownidKey = UserInfoManager.shared.ownidKey else {
                    return
                }
                NetEngine.getJoinId(ownidKey:ownidKey, meetingid: number!) { (result) in
                    let model = SJJoinModel.deserialize(from: result)
                    switch model?.code {
                    case 0:
                        let roomId = PE.toString(obj: model!.roomId)
                        let hostId = model?.status == 1 ? model?.joinid:UserInfoManager.shared.hostId
                        let token = model?.status == 1 ? model?.token:UserInfoManager.shared.token
                        let zak = model?.status == 1 ? model?.zak:UserInfoManager.shared.zak
                        if model?.status == 1  {
                            RtcEngine.saveDataJoin(mode: model!)
                        }
                        
                        var info = ZoomApiInfo()
                        info.meetingNumber = roomId
                        info.displayName = username!
                        info.userID = hostId!
                        info.userToken = token
                        info.zak = zak
                        info.isAuidoOff = UserInfoManager.shared.onAudio!
                        info.isVideoOff = UserInfoManager.shared.onVideo!
                        info.ownid = number
                        info.password = model?.password ?? ""
                        if model?.presenter == 0 {
                            RtcEngine.doJoinMeeting(info: info)
                        }else {
                            RtcEngine.doHostMeeting(info: info)
                        }
                        
                        if success != nil {
                            success!(result)
                        }
                    default:
                        show_msg((model?.msg)!)
                    }
                }
            }
            
        }
    }
    
    class func rtcSetting() -> () {
        ZoomsdkManger.shared.rtcSetting()
    }
    
    class func doHostMeeting(info:ZoomApiInfo) {
        RtcEngine.rtcSetting()
        ZoomsdkManger.shared.doHostMeeting(info: info, delegatek: RtcEngine.shared )
    }
    
    class func doJoinMeeting(info:ZoomApiInfo) {
        RtcEngine.rtcSetting()
        ZoomsdkManger.shared.doJoinMeeting(info: info, delegatek: RtcEngine.shared)
    }
    
}


extension RtcEngine: ZoomSDKMeetingServiceDelegate {
    
    func onMeetingStatusChange(_ state: ZoomSDKMeetingStatus, meetingError error: ZoomSDKMeetingError, end reason: EndMeetingReason) {
        switch state {
        case ZoomSDKMeetingStatus_Idle:
            break
        case ZoomSDKMeetingStatus_Ended:
            WssEngine.shared.disconnect()
            TrtcEngine.exit()
        case ZoomSDKMeetingStatus_Leave_Breakout_Room:
            TrtcEngine.exit()
        case ZoomSDKMeetingStatus_Connecting:
            HUD.dismiss()
            TrtcEngine.enter()
            break
        case ZoomSDKMeetingStatus_InMeeting:
            self.setupAfterCustom()
            self.addNotification()
            WssEngine.shared.connect()
            break
        case ZoomSDKMeetingStatus_InWaitingRoom:
            break
        default:
            break
        }
    }
}

//MARK:-通知
extension RtcEngine {
    @objc func receiveQustion(not:Notification) {
        guard let object = (not.object as? String) else {
            return
        }
        let mode = WebSocketMode.deserialize(from: object)
        self.questionMode = mode
        
        if ZoomsdkManger.isMeetingHost() == false {
            self.voteAction()
        }
        self.kZoomView.isHidden = false
        
    }
}

extension RtcEngine:AmuneDelegate {
    func amune_action(viewController: AmuneViewController, senber: KIcon?) {
       
        switch senber!.tag {
        case 100:
            if UserInfoManager.shared.isOnLive == true {
                viewController.isLiving = !viewController.isLiving
                let s = viewController.isLiving ? "开启直播":"关闭直播"
                senber?.title.stringValue = s.localized()
                ZoomsdkManger.shared.setLive(!viewController.isLiving)
            }else {
                show_msg("联系客服开通，并且在设置开启".localized())
            }
        case 101:
            self.voteAction()
        default:
            break
        }
    }
    
}


extension String {
    func clear_ownid() -> String {
        if self[0] == "c" {
            return self.substring(fromIndex: 1)
        }
        return self
    }
}

extension String {
    func url(parms:[String:String]?) -> String {
        guard let dict = parms else {
            return self
        }
        
        var urlString:String = ""
        for (_,key) in dict.keys.enumerated() {
            let value = dict[key]
            if value != nil {
                urlString = (urlString+"&"+key+"="+value!)
            }
        }
        
        if urlString[0] == "&" {
            urlString.remove(at: startIndex)
            urlString.insert("?", at: startIndex)
        }
        return self+urlString
    }
}

